/**
* 
* @brief	温湿度采集服务
* @author	yun
* @date		2016-12-28
* @desc		设备温湿度采集服务
* @version	v0.1
*
*/

#include	"service_temp.h"

#include	"app_conf.h"
#include	"cmsis_os.h"

#include	"platform_logger.h"
#include	"platform_temp.h"
#include	"platform_calendar.h"

#include	"service_server.h"

#define		SERVICE_TEMP_ID			"temp-humd"


#define		SERVICE_TEMP_FORMAT		\
"{\"type\":\"state\",\"data\":{\"temp\":%0.1f,\"humd\":%0.0f}}"

typedef struct {
	float	temperature;
	float	humidity;
	int 	error;
}temp_measure_t;

static temp_measure_t temp_measture_v;

static 	osThreadId		thread_temp_id = NULL;
static 	osMessageQId 	temp_event_queue = NULL;
static  osMessageQId	temp_query_queue = NULL;

static int  temp_measure(int time);
static void thread_temp(void const *argument);
static int  temp_measure_callback(float t, float h, int err);


// 创建温湿度服务
int service_temp_establish(void){
	osThreadDef(Temp, thread_temp, osPriorityAboveNormal, 0, 256);
	thread_temp_id = osThreadCreate(osThread(Temp), NULL);
	if(thread_temp_id == NULL){
		log_error_printf("service: create temp err");
		return -1;
	}
	
	return 0;
}

// 销毁温湿度服务
int service_temp_destroy(void){
	if(thread_temp_id != NULL){
		osThreadTerminate(thread_temp_id);
		thread_temp_id = NULL;
	}
	//
	if(temp_event_queue != NULL){
		vQueueDelete(temp_event_queue);
		temp_event_queue = NULL;
	}
	//
	if(temp_query_queue != NULL) {
		vQueueDelete(temp_query_queue);
		temp_query_queue = NULL;
	}
	// 延时，等待任务销毁完成
	osDelay(10);
	return 0;
}


//
// 主动查询温湿度值
// 当设备登陆时，需要即使上次温湿度的值
//
int service_temp_query(void){
	if (temp_query_queue != NULL){
		osMessagePut(temp_query_queue, 1, 100);
	}
}


extern volatile unsigned char temp_input_bits;

//
// 温湿度服务线程
//
static void thread_temp(void const *argument){
	log_info_printf("thread: temperature & humidity");
	
	temp_event_queue = xQueueCreate(1, sizeof(temp_measure_t *));
	if(temp_event_queue == NULL){
		log_error_printf("temp: create measure message error");
		app_state_notification(APP_ERR);
		osThreadTerminate(NULL);
	}
	
	temp_query_queue = xQueueCreate(1, sizeof(int));
	if (temp_query_queue == NULL) {
		log_error_printf("temp: create query semaphore error");
		app_state_notification(APP_ERR);
		osThreadTerminate(NULL);
	}
	
	char packet[80];
	
	while(1){
		
		// 稳定查询测量时间间隔
		//osDelay(SEV_TEMP_HUMD_QUERY_INTERVAL);
		osMessageGet(temp_query_queue, SEV_TEMP_HUMD_QUERY_INTERVAL);
		
		if(temp_measure(2) == 0) {
			temp_measure_t * temp_measure = &temp_measture_v;
			if(temp_measure->error == 0){
				int len = sprintf(packet, SERVICE_TEMP_FORMAT, 
					temp_measure->temperature, temp_measure->humidity);
				server_send_data(SERVICE_TEMP_ID, packet);
				log_notice_printf("temp: %s", packet);
			} else {
				log_warning_printf("temp: measure error code=%d", temp_input_bits);	
			}
		} else {
			log_warning_printf("temp: measure error");	
		}	
	}
}

//
// 温度测量 time: 次数
// 
static int  temp_measure(int time){
	int err = 0;
	for(int i=0; i<time; i++){
		platform_temp_start_measure(temp_measure_callback);
		osDelay(10);
		osEvent event = osMessageGet(temp_event_queue, 100);
		if(event.status == osEventMessage){
			err = 0;
		} else {
			err = -1;
		}
		platform_temp_stop_measure();
		// 2秒间隔测量一次
		if(i != time -1){
			 osDelay(2000);
		}
	}
	return err;
}

//
// 测量完成回调函数
//
static int temp_measure_callback(float h, float t, int err){
	// 每开启一次智能得到一次结果，因此可以用全局变量
	temp_measture_v.temperature = t;
	temp_measture_v.humidity = h;
	temp_measture_v.error = err;

	// 发送消息
	if(temp_event_queue != NULL){
		if(osMessagePut(temp_event_queue, (int)&temp_measture_v, 100) != osOK){
			return -1;
		}
	}

	return 0;
}



